<?php
declare(strict_types=1);

use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\EventDispatcher\ListenerProviderInterface;
use Psr\EventDispatcher\StoppableEventInterface;

/**
 * 事件调度器
 * Class EventDispatcher
 */
class EventDispatcher implements EventDispatcherInterface
{
    /**
     * @var ListenerProviderInterface
     */
    public $listenerProvider;

    /**
     * EventDispatcher constructor.
     * @param EventListenerInterface[]|string[] $listeners
     */
    public function __construct(array $listeners)
    {
        $this->listenerProvider = new ListenerProvider($listeners);
    }

    /**
     * 派发当前事件到所有监听器的处理方法process
     * @param object $event 当前事件对象
     * @return object
     */
    public function dispatch(object $event): object
    {
        foreach ($this->listenerProvider->getListenersForEvent($event) as $callback) {
            try {
                call_user_func($callback, $event);
            } catch (Throwable $ex) {
                Logger::error(__METHOD__ . '调度异常：' . $ex->getMessage());
            }
            if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {
                break;
            }
        }
        return $event;
    }
}
